/**
 * Copyright (C) 2013  Mykola Bespaliuk
 */

var options = options || {};
/**
 * Default options
 */
options.defaults = {
    "option_use_short_url": "keep_long_url"
};
/**
 * Option prefix in the localStorage
 */
options.prefix  = "option_";
/**
 * Pattern to match options in the localStorage
 */
options.pattern = new RegExp( "^" + options.prefix + "\\w+$" );
/**
 * Html inputs that represent options
 */
options.inputs  = document.getElementsByClassName( 'option' );
/**
 * Options that need trigger key to be selected
 */
options.requiresTrigger = {
    "short_url_trigger": [ "use_goo_gl", "use_tiny_url" ]
};

/**
 * Saving options to localStorage
 * @param event
 */
options.saveOptions = function( event ) {
    event.preventDefault();
    var i,
        inputs = options.inputs,
        prefix = options.prefix;

    options.purgeOptions();

    for( i in inputs ) {
        if( inputs.hasOwnProperty( i ) && inputs.propertyIsEnumerable( i ) ) {
            if( inputs[i] instanceof HTMLInputElement && inputs[i].type == "radio" && inputs[i].checked ) {
                localStorage[prefix + inputs[i].name] = inputs[i].id;
            } else if( inputs[i] instanceof HTMLSelectElement && !inputs[i].disabled ) {
                localStorage[prefix + inputs[i].id] = inputs[i].value;
            }
        }
    }
    options.reportSaved();
};

/**
 * Setting options to defaults
 * @param event
 */
options.resetOptions = function( event ) {
    event.preventDefault();
    var i,
        defaults  = options.defaults;

    options.purgeOptions();

    for( i in defaults ) {
        if( defaults.hasOwnProperty( i ) && defaults.propertyIsEnumerable( i ) ) {
            localStorage[i] = defaults[i];
        }
    }
    //TODO: maybe make it more versatile later
    defaults['option_short_url_trigger'] = "Ctrl";
    options.setUpInputs( defaults );
    options.resetTrigger( true );
    options.reportSaved();
};

/**
 * Cleaning all the application's options
 */
options.purgeOptions = function() {
    var i, pattern = options.pattern;
    for( i in localStorage ) {
        if( localStorage.hasOwnProperty(i) && i.match( pattern ) ) {
            delete localStorage[i];
        }
    }
};

/**
 * Getting the options from the localStorage and
 * making corresponding changes to the form
 */
options.restoreOptions = function() {
    var i,
        optionsToRestore = {},
        defaults         = options.defaults,
        pattern          = options.pattern;

    //noinspection JSUnusedGlobalSymbols
    Object.defineProperty( optionsToRestore,
        "length",
        {
            value: 0,
            writable: true,
            enumerable: false,
            configurable: true
        }
    );
    // collections options from localStorage
    for( i in localStorage ) {
        if( localStorage.hasOwnProperty( i ) && localStorage.propertyIsEnumerable( i ) ) {
            if( i.match( pattern ) ) {
                optionsToRestore[i] = localStorage[i];
                optionsToRestore.length += 1;
            }
        }
    }
    //setting localStorage's options to defaults in case they are empty
    if( optionsToRestore.length == 0 ) {
        optionsToRestore = defaults;
        for( i in defaults ) {
            if( defaults.hasOwnProperty( i ) && defaults.propertyIsEnumerable( i ) ) {
                localStorage[i] = defaults[i];
            }
        }
        options.resetTrigger( false );
        //TODO: maybe make it more versatile later
    } else if( optionsToRestore['option_use_short_url'] == "keep_long_url" ) {
        options.resetTrigger( true );
    }

    options.setUpInputs( optionsToRestore );
};

/**
 * Making changes to the form corresponding to given options
 * @param optionsObject
 */
options.setUpInputs = function( optionsObject ) {
    var i,
        j,
        inputs = options.inputs,
        prefix = options.prefix;

    for( i in optionsObject ) {
        if( optionsObject.hasOwnProperty( i ) && optionsObject.propertyIsEnumerable( i ) ) {
            for( j in inputs ) {
                if( inputs.hasOwnProperty( j ) && inputs.propertyIsEnumerable( j ) ) {
                    if( inputs[j] instanceof HTMLInputElement
                        && inputs[j].type == "radio"
                        && i == ( prefix + inputs[j].name )
                        && optionsObject[i] == inputs[j].id ) {
                        inputs[j].checked = true;
                    } else if( inputs[j] instanceof HTMLSelectElement && i == ( prefix + inputs[j].id ) ) {
                        inputs[j].value = optionsObject[i];
                    }
                }
            }
        }
    }
};

/**
 * Making trigger selection unavailable for the options
 * which don't need trigger
 * @param event
 */
options.manageTriggers = function( event ) {
    var needsTrigger = options.requiresTrigger,
        i, j,
        triggers = document.getElementById( "short_url_trigger" );

    triggers.disabled = true;
    //if trigger id is in the mapping - enable it
    for( i in needsTrigger ) {
        if( needsTrigger.hasOwnProperty( i ) && needsTrigger.propertyIsEnumerable( i ) ) {
            for( j = 0; j < needsTrigger[i].length; j += 1 ) {
                if( event.target.id == needsTrigger[i][j] ) {
                    triggers.disabled = !( triggers.id == i );
                }
            }
        }
    }
};
/**
 * disable trigger selection
 */
options.resetTrigger = function( bool ) {
    var trigger = document.getElementById( 'short_url_trigger' );
    trigger.disabled = bool;
};

/**
 * Display status message
 */
options.reportSaved = function() {
    var status = document.getElementById( 'options_saved' );
    status.style.opacity = 1;
    setTimeout( function() {
        status.style.opacity = 0;
    }, 750 );
};

/**
 * Translating the elements with data-message attribute
 */
options.translatePage = function() {
    var objects = document.getElementsByTagName('*'), i;
    for(i = 0; i < objects.length; i++) {
        if (objects[i].dataset && objects[i].dataset.message) {
        //noinspection JSUnresolvedVariable, JSUnresolvedFunction
            objects[i].innerHTML = chrome.i18n.getMessage(objects[i].dataset.message);
        }
    }
};

/**
 * Entry point
 */
options.initialize = function() {
    options.resetTrigger( false );
    options.translatePage();
    options.restoreOptions();
};

/**
 * Initialization of event listeners
 */
( function() {
    var saveButton  = document.getElementById( "options_save" ),
        resetButton = document.getElementById( "options_reset" ),
        checkBoxes  = document.getElementsByName( "use_short_url" ),
        tinyUrlLink = document.getElementById( "tiny_url_link" ),
        googleLink  = document.getElementById( "google_link" ),
        i;

    document.addEventListener( 'DOMContentLoaded', options.initialize );
    saveButton.addEventListener( 'click', options.saveOptions );
    resetButton.addEventListener( 'click', options.resetOptions );
    for( i in checkBoxes ) {
        if( checkBoxes.hasOwnProperty( i ) && checkBoxes.propertyIsEnumerable( i ) ) {
            checkBoxes[i].addEventListener( 'change', options.manageTriggers );
        }
    }
    tinyUrlLink.addEventListener( 'click', function() {
        analytics.trackTinyUrlVisit();
    } );
    googleLink.addEventListener( 'click', function() {
        analytics.trackGooGlVisit();
    } );
} )();